"""
此模块是获取图像逆透视变换矩阵
============================
例子:执行逆变换
----
import cv2
from InvPersectiveTrans import *
A = [[200, 0], [373, 0], [0, 418], [579, 418]]
B = [[81, 0], [485, 0], [81, 418], [485, 418]]
m = GetTransformM(A,B)
print(m)
img = cv2.imread('data/test2.jpg')
res = TransformTest(img,m)
cv2.imshow("src", img)
cv2.imshow("result", res)
cv2.waitKey(0)

"""


import numpy as np
import cv2

def GetTransformM(A:list[list], B:list[list]):
    """
    获取变换矩阵 A 是原坐标点 B 是变化后的坐标点\n
    例子：\n
    A_ = [[75, 0], [137, 0], [22, 89], [189, 89]]\n
    B_ = [[41, 0], [158, 0], [41, 89], [158, 89]]\n
    res = GetTransformM(A_, B_)\n
    """
    mata = np.mat([
        [*A[0], 1, 0, 0, 0, -A[0][0] * B[0][0], -A[0][1] * B[0][0]],
        [0, 0, 0, *A[0], 1, -A[0][0] * B[0][1], -A[0][1] * B[0][1]],
        [*A[1], 1, 0, 0, 0, -A[1][0] * B[1][0], -A[1][1] * B[1][0]],
        [0, 0, 0, *A[1], 1, -A[1][0] * B[1][1], -A[1][1] * B[1][1]],
        [*A[2], 1, 0, 0, 0, -A[2][0] * B[2][0], -A[2][1] * B[2][0]],
        [0, 0, 0, *A[2], 1, -A[2][0] * B[2][1], -A[2][1] * B[2][1]],
        [*A[3], 1, 0, 0, 0, -A[3][0] * B[3][0], -A[3][1] * B[3][0]],
        [0, 0, 0, *A[3], 1, -A[3][0] * B[3][1], -A[3][1] * B[3][1]],
    ], dtype=np.float32)

    matb = np.mat([*B[0], *B[1], *B[2], *B[3]]).T

    val = np.linalg.solve(mata, matb).T

    val = np.mat([
        [val[0, 0], val[0, 1], val[0, 2]],
        [val[0, 3], val[0, 4], val[0, 5]],
        [val[0, 6], val[0, 7], 1.0],
    ])
    return val


def TransformTest(image,m:np.matrix):
    maxx=len(image[0])
    maxy=len(image)
    
    res:cv2.Mat = image.copy()
    res.fill(125)
    minv = m.I
    for x in range(maxx):
        for y in range(maxy):
            cood = np.mat([x,y,1]).T
            tmp = minv * cood
            tmp = tmp/tmp[2][0]
            newx = tmp[0,0]
            newy = tmp[1,0]
            if newx>=0 and newx<maxx and newy>=0 and newy<maxy:
                res[y][x]=image[int(newy)][int(newx)]

    return res
    


